/*
 * Copyright (c) 2009 LastFM.Desktop Anton Pavlik.
 * All Rights Reserved.
 * 
 * You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, 
 * with or without modifications, and in Source or Object form, provided that You meet the following 
 * conditions:
 * 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
 *
 * 2. You must cause any modified files to carry prominent notices stating that You changed the files; 
 * and
 *
 * 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, 
 * patent, trademark, and attribution notices from the Source form of the Work, excluding those notices 
 * that do not pertain to any part of the Derivative Works.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * You may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, Licensor provides the Work 
 * (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
 * CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties 
 * or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. 
 * YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING OR REDISTRIBUTING THE WORK
 * AND ASSUME ANY RISKS ASSOCIATED WITH YOUR EXERCISE OF PERMISSIONS UNDER THIS LICENSE. 
 */
package org.shake.lastfm;

import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.shake.lastfm.model.Playlist;
import org.shake.lastfm.model.Track;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class Parser implements ErrorHandler
{

    private InputStream playlistStream;
    private Playlist playlist;

    private final static String KEY_TITLE = "title";
    private final static String KEY_ANNOTATION = "annotation";
    private final static String KEY_CREATOR = "creator";
    private final static String KEY_INFO = "info";
    private final static String KEY_LOCATION = "location";
    private final static String KEY_LICENSE = "license";
    private final static String KEY_DURATION = "duration";

    private final static String KEY_IMAGE = "image";
    private final static String KEY_TRACKLIST = "trackList";
//    private final static String KEY_PLAYLIST = "playlist";
    
    private final static String KEY_LINK = "link";

    private final static String KEY_TRACK = "track";

    private final static String KEY_IDENTIFIER = "id";
    private final static String KEY_ALBUM = "album";

    public Parser(InputStream stream)
    {
        this.playlistStream = stream;
    }

    public Playlist parse() throws Exception
    {
        SAXBuilder parser = new SAXBuilder();
        parser.setErrorHandler(this);
        parser.setValidation(false);

        Document doc = parser.build(this.playlistStream);
        Element root = doc.getRootElement();

        playlist = new Playlist();
        
        Element node = root.getChild(KEY_TITLE);
        if (node != null)
            playlist.setTitle(node.getValue());

        node = root.getChild(KEY_ANNOTATION);
        if (node != null)
            playlist.setAnnotation(node.getValue());

        node = root.getChild(KEY_CREATOR);
        if (node != null)
            playlist.setCreator(node.getValue());

        node = root.getChild(KEY_INFO);
        if (node != null)
            playlist.setInfo(node.getValue());

        node = root.getChild(KEY_LICENSE);
        if (node != null)
            playlist.setLicense(node.getValue());

        node = root.getChild(KEY_LINK);
        if (node != null)
        {
            playlist.setRefreshAfter(Integer.valueOf(node.getValue()));
        }

        node = root.getChild(KEY_TRACKLIST);

        List trackList = node.getChildren(KEY_TRACK);

        Iterator it = trackList.iterator();
        Track track = null;
        Element node2 = null;

        while (it.hasNext())
        {
            node = (Element) it.next();
            track = new Track();

            node2 = node.getChild(KEY_LOCATION);
            if (node2 != null)
                track.setLocation(node2.getValue());

            node2 = node.getChild(KEY_TITLE);
            if (node2 != null)
                track.setTitle(node2.getValue());

            node2 = node.getChild(KEY_ANNOTATION);
            if (node2 != null)
                track.setAnnotation(node2.getValue());

            node2 = node.getChild(KEY_IMAGE);
            if (node2 != null)
                track.setImage(node2.getValue());

            node2 = node.getChild(KEY_INFO);
            if (node2 != null)
                track.setInfo(node2.getValue());

            node2 = node.getChild(KEY_CREATOR);
            if (node2 != null)
                track.setCreator(node2.getValue());

            node2 = node.getChild(KEY_ALBUM);
            if (node2 != null)
                track.setAlbum(node2.getValue());

            node2 = node.getChild(KEY_IDENTIFIER);
            if (node2 != null)
                track.setId(node2.getValue());

            node2 = node.getChild(KEY_DURATION);
            if (node != null)
            {
                try
                {
                    track.setDuration(Long.valueOf(node2.getValue()));
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }

            this.playlist.addTrack(track);
        }

        this.playlistStream.close();

        return this.playlist;
    }

    public static void listChildren(Element current, int depth)
    {

        printSpaces(depth);
        System.out.println(current.getName());
        List children = current.getChildren();
        Iterator iterator = children.iterator();
        while (iterator.hasNext())
        {
            Element child = (Element) iterator.next();
            listChildren(child, depth + 1);
        }

    }

    private static void printSpaces(int n)
    {
        for (int i = 0; i < n; i++)
        {
            System.out.print(' ');
        }
    }

    public void error(SAXParseException exception) throws SAXException
    {
    }

    public void fatalError(SAXParseException exception) throws SAXException
    {
    }

    public void warning(SAXParseException exception) throws SAXException
    {
    }
}